let MqttConfig = {
	host: '',
	userName: '',
	passWord: '',
	clientId: '',
	// 以下为非必须参数
	keepAliveInterval: 60, //心跳时间，单位s。即多长时间确认一次Client端是否在线，默认值60
	connectionTimeout: 30, //超时时间，单位s，默认值30s
	automaticReconnect: true, //断开后，是否自动连接，默认false，不使
	cleanSession: false, //清除会话标志，默认true，该功能启用(false)会自动断线重连
	//0 —— 开启会话重用机制。网络断开重连后，恢复之前的Session信息。需要客户端和服务器有相关Session持久化机制。
	//1 —— 关闭会话重用机制。每次Connect都是一个新Session，会话仅持续和网络连接同样长的时间。
	maxInflight: 10, // 允许同时发送几条消息（未收到broker确认信息)
	will: { //遗言
		topic: '',
		payload: 'payload',
		qos: 0,
		retained: true
	}
}

export default class MQTT {
	$mqtt = null
	connectState = false

	constructor() {
		this.init()

	}
	snedGlobalMsg(msgPayload) {
		uni.$emit('onMqttMsg', msgPayload)
	}
	//初始化mqtt
	init() {
		this.$mqtt = uni.requireNativePlugin('mqtt-plugin')
		this.connectMqtt()
	}
	
	//连接mqtt
	connectMqtt() {
		let params = MqttConfig
		//每次订阅mqtt事件后 ，当监听到mqtt发起的订阅事件会走第二个参数回调函数
		this.$mqtt.mqttInit(params, (res) => { //包装一层箭头函数防止MqttResponseCallBackFunc方法内部得this指向出现问题
			this.MqttResponseCallBackFunc(res)
		})
	}
	
	/**
	 * 关闭mqtt客户端
	 */
	closeMqtt(){
		if (!this.$mqtt || !this.connectState) return
		this.$mqtt.shutdown({})
	}
	
	//监听订阅mqtt事件后响应的消息
	MqttResponseCallBackFunc(res) {
		this.snedGlobalMsg(res) //向项目全局发送mqtt订阅后接收到得事件
		// switch (res) {
		// 	case '连接成功':
		// 		if (!this.connectState) this.connectState = true
		// 		break
		// 	case '连接失败':
		// 	case '断开成功':
		// 		if (this.connectState) this.connectState = false
		// 		this.$mqtt = null
		// 		break
		// }
		
	}
	
	/**
	 * 订阅mqtt事件
	 * @param {Object} topic 事件名 
	 */
	subscript(topic, qos=0) {
		return new Promise((resolve, reject) => {
			this.$mqtt.subscribe({ topic, qos }, res => {
				resolve(res)
			})
		})
	},
	
	/**
	 * 批量订阅事件
	 * @param {Object} topic 事件名数组列表 
	 */
	subscribeAll(topics) {
		return new Promise((resolve, reject) => {
			this.$mqtt.batchSubscribe(topics, res => {
				resolve(res)
			})
		})
	},
	
	/**
	 * 向mqtt发布事件
	 * @param {Object} topic 事件名 
	 */
	publish(topic, qos=0, message="") {
		
		return new Promise((resolve, reject) => {
			this.$mqtt.publish({ message, qos, topic }, res => {
				resolve(res)
			})
		})
	}
	
	/**
	 * 
	 * @description 
	 * 就是对mqtt发布订阅消息做了一层封装，先订阅mqtt事件消息，防止我们向mqtt发送消息后，mqtt响应回的消息我们由于没有提前进行订阅而接收不到。
	 * 所以通常情况下使用mqtt与设备进行通信，在发布mqtt消息前一定需要订阅对应的mqtt响应的事件。所以我们这里进行了简化，订阅指定的mqtt消息后再向mqtt发布消息。
	 * 配网 / 获取属性 / 控制机器
	 * @param pTopic 需要向mqtt发布的事件名
	 * @param sTopic 订阅mqtt的事件名
	 */
	properties(pTopic, sTopic, qos=0, message="") {
		return new Promise((resolve, reject) => {
			 //先订阅事件 防止我们下一步给设备发送事件后 设备响应回来的事件我们无法接受也就无法知道设备响应给我们的结果
			this.subscript(sTopic, qos).then(sRes => {
				if (sRes) {
					console.log('订阅mqtt事件成功，事件名:',sTopic)
					//向mqtt发送事件
					this.publish(pTopic, qos, message).then(pRes => {
						if (pRes) {
							console.log('向mqtt发布消息成功,消息名:',pTopic)
							resolve(true)
						} else {
							console.log(`向mqtt发布${pTopic}消息失败`)
							reject(false) }
					})
				} else { 
							console.log(`向mqtt订阅${sTopic}消息失败`)
					reject(false) }
			})
		})
	},
}